package com.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.log4j.Logger;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.web.jsf.FacesContextUtils;

import com.builder.TipoDeMovimientoBuilder;
import com.dao.BaseModelDAO;
import com.model.TipoDeMovimiento;
import com.query.TipoDeMovimientoQuery;
import com.util.JSFUtil;
import com.util.TipoMovimientoEnum;
import com.view.TipoDeMovimientoView;

@ManagedBean
@ViewScoped
@SuppressWarnings("serial")
public class TipoDeMovimientoController extends PaginableController<TipoDeMovimiento> {

	private Logger log = Logger.getLogger(TipoDeMovimientoController.class);
	private BaseModelDAO<TipoDeMovimiento> dao;
	private TipoDeMovimiento tipoDeMovimiento;
	private TipoDeMovimientoQuery tipoDeMovimientoQuery;

	@ManagedProperty("#{tipoDeMovimientoView}")
	private TipoDeMovimientoView tipoDeMovimientoView;

	@ManagedProperty("#{tipoDeMovimientoBuilder}")
	private TipoDeMovimientoBuilder tipoDemovimientoBuilder;

	@SuppressWarnings("unchecked")
	public TipoDeMovimientoController() {
		try {
			dao = (BaseModelDAO<TipoDeMovimiento>) FacesContextUtils
					.getWebApplicationContext(FacesContext.getCurrentInstance())
					.getBean("tipoDeMovimientoDAO");
			tipoDeMovimientoQuery = new TipoDeMovimientoQuery();
			addEdit = false;

		} catch (Throwable e) {
			log.error("Error al inicializar la clase TipoDeMovimientoController", e);
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Error al realizar la operacion", ""));
		}
	}


	public void query(ActionEvent event) {
		loadList();
	}

	public void edit(ActionEvent event) {
		try {
			tipoDeMovimiento = (TipoDeMovimiento) lazyDM.getRowData();
			tipoDeMovimiento = dao.findFULL(tipoDeMovimiento.getID());
			tipoDeMovimientoView = tipoDemovimientoBuilder.toView(tipoDeMovimiento);
			addEdit = true;
			
		} catch (Throwable e) {
			log.error("Error al editar", e);
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Error al realizar la operacion", ""));
		}
	}

	public void delete(ActionEvent event) {
		try {
			tipoDeMovimiento = (TipoDeMovimiento) lazyDM.getRowData();
			dao.delete(tipoDeMovimiento);
			loadList();
		} catch (Throwable e) {
			log.error("Error al eliminar", e);
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Error al realizar la operacion", ""));
		}
	}

	public void add(ActionEvent event) {
		addEdit = true;
		clear();
	}

	public void save(ActionEvent event) {
		try {
			tipoDeMovimiento = tipoDemovimientoBuilder.toDomain(tipoDeMovimientoView);

			if (tipoDeMovimiento.getID() != null) {
				dao.edit(tipoDeMovimiento);
				addEdit = false;
			} else {
				dao.save(tipoDeMovimiento);
			}
			clear();
			JSFUtil.saveMessage("Elemento guardado con exito",
					FacesMessage.SEVERITY_INFO);
			if (!addEdit) {
				loadList();
			}
		} catch (DataIntegrityViolationException e) {
			JSFUtil.saveMessage(
					"Error al guardar: El usuario debe ser unico en el sistema.",
					FacesMessage.SEVERITY_ERROR);
		} catch (Throwable e) {
			log.error("Error al guardar", e);
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Error al realizar la operacion", ""));
		}
	}

	public void cancel(ActionEvent event) {
		addEdit = false;
		lazyDM = null;
	}

	public void clear() {
		tipoDeMovimiento = new TipoDeMovimiento();
		tipoDeMovimientoView = new TipoDeMovimientoView();
	}

	private void loadList() {

		lazyDM = new LazyDataModel<TipoDeMovimiento>() {
			@Override
			public List<TipoDeMovimiento> load(int first, int pageSize,
					String sortField, SortOrder sortOrder,
					Map<String, Object> filters) {

				Map<String, Object> filtro = new HashMap<String, Object>();
				filtro.put("descripcion", tipoDeMovimientoQuery.getDescripcion());
				return dao.getList(first, pageSize, "descripcion", true, filtro,
						true);
			}
		};

		Map<String, Object> filtro = new HashMap<String, Object>();
		filtro.put("descripcion", tipoDeMovimientoQuery.getDescripcion());
		lazyDM.setRowCount(dao.count(filtro, true).intValue());
	}

	public TipoMovimientoEnum[] getTipoMovimientoEnumValues() {
		return TipoMovimientoEnum.values();
	}
	  
	  
	public Logger getLog() {
		return log;
	}


	public void setLog(Logger log) {
		this.log = log;
	}


	public BaseModelDAO<TipoDeMovimiento> getDao() {
		return dao;
	}


	public void setDao(BaseModelDAO<TipoDeMovimiento> dao) {
		this.dao = dao;
	}


	public TipoDeMovimiento getTipoDeMovimiento() {
		return tipoDeMovimiento;
	}


	public void setTipoDeMovimiento(TipoDeMovimiento tipoDeMovimiento) {
		this.tipoDeMovimiento = tipoDeMovimiento;
	}


	public TipoDeMovimientoQuery getTipoDeMovimientoQuery() {
		return tipoDeMovimientoQuery;
	}


	public void setTipoDeMovimientoQuery(TipoDeMovimientoQuery tipoDeMovimientoQuery) {
		this.tipoDeMovimientoQuery = tipoDeMovimientoQuery;
	}


	public TipoDeMovimientoView getTipoDeMovimientoView() {
		return tipoDeMovimientoView;
	}


	public void setTipoDeMovimientoView(TipoDeMovimientoView tipoDeMovimientoView) {
		this.tipoDeMovimientoView = tipoDeMovimientoView;
	}


	public TipoDeMovimientoBuilder getTipoDemovimientoBuilder() {
		return tipoDemovimientoBuilder;
	}


	public void setTipoDemovimientoBuilder(
			TipoDeMovimientoBuilder tipoDemovimientoBuilder) {
		this.tipoDemovimientoBuilder = tipoDemovimientoBuilder;
	}

}
